package com.jeesite.modules.pay.wxpay.api;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import net.glxn.qrgen.core.image.ImageType;
import net.glxn.qrgen.javase.QRCode;

import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import sun.misc.BASE64Encoder;

@Controller
@Scope("prototype")
@RequestMapping("${frontPath}/tenpay")
public class TenPayController {

	/*
	 * @Autowired private PayRecordService payRecordService;
	 * 
	 * @Autowired private AppCustomerService appCustomerService;
	 */
	private String out_trade_no = "";

	// https://api.mch.weixin.qq.com/pay/unifiedorder

	/**
	 * 生成预支付订单，获取prepayId
	 * 
	 * @param request
	 * @param response
	 * @return
	 * @throws Exception
	 */
	// @Auth
	@RequestMapping(value = "prepay")
	public @ResponseBody
	Map<String, Object> getOrder(HttpServletRequest request,
			HttpServletResponse response) throws Exception {
		Map<String, Object> map = new HashMap<String, Object>();
		// 获取生成预支付订单的请求类
		PrepayIdRequestHandler prepayReqHandler = new PrepayIdRequestHandler(
				request, response);

		// System.out.println(microPay(new
		// HashMap<String,String>(),3000,3000,prepayReqHandler));

		String totalFee = request.getParameter("total_fee");
		int total_fee = (int) (Float.valueOf(totalFee) * 100);
		System.out.println("total:" + total_fee);
		System.out.println("total_fee:" + total_fee);
		prepayReqHandler.setParameter("appid", ConstantUtil.APP_ID);
		prepayReqHandler.setParameter("body", ConstantUtil.BODY);
		prepayReqHandler.setParameter("mch_id", ConstantUtil.MCH_ID);
		String nonce_str = WXUtil.getNonceStr();
		prepayReqHandler.setParameter("nonce_str", nonce_str);
		prepayReqHandler.setParameter("notify_url", ConstantUtil.NOTIFY_URL);
		out_trade_no = String.valueOf(UUID.next());
		prepayReqHandler.setParameter("out_trade_no", out_trade_no);
		prepayReqHandler.setParameter("spbill_create_ip",
				request.getRemoteAddr());
		String timestamp = WXUtil.getTimeStamp();
		prepayReqHandler.setParameter("time_start", timestamp);
		System.out.println(String.valueOf(total_fee));
		prepayReqHandler.setParameter("total_fee", String.valueOf(total_fee));
		prepayReqHandler.setParameter("trade_type", "MWEB");// JSAPI NATIVE
															// APP
		/**
		 * 注意签名（sign）的生成方式，具体见官方文档（传参都要参与生成签名，且参数名按照字典序排序，最后接上APP_KEY,转化成大写）
		 */
		prepayReqHandler.setParameter("sign", prepayReqHandler.createMD5Sign());
		prepayReqHandler.setGateUrl(ConstantUtil.GATEURL);
		String prepayid = prepayReqHandler.sendPrepay();
		// 若获取prepayid成功，将相关信息返回客户端
		if (prepayid != null && !prepayid.equals("")) {

			/*
			 * PayRecord payRecord=new PayRecord(); AppCustomer
			 * appCustomer=(AppCustomer)
			 * request.getSession().getAttribute("appCustomer");
			 */

			/*
			 * payRecord.setPhone(appCustomer.getPhone());
			 * payRecord.setSerialId(Long.valueOf(out_trade_no));
			 * payRecord.setType((byte)2); payRecord.setGenerateTime(new
			 * Date()); payRecord.setTotalAmount(Float.valueOf(total_fee)/100);
			 * 
			 * payRecordService.insert(payRecord);
			 */

			String signs = "appid=" + ConstantUtil.APP_ID + "&noncestr="
					+ nonce_str + "&package=Sign=WXPay&partnerid="
					+ ConstantUtil.PARTNER_ID + "&prepayid=" + prepayid
					+ "&timestamp=" + timestamp + "&key="
					+ ConstantUtil.APP_KEY;
			map.put("code", 0);
			map.put("info", "success");
			map.put("prepayid", prepayid);

			/**
			 * 签名方式与上面类似
			 */

			map.put("sign", MD5Util.MD5Encode(signs, "utf8").toUpperCase());
			map.put("appid", ConstantUtil.APP_ID);
			map.put("timestamp", timestamp); // 等于请求prepayId时的time_start
			map.put("noncestr", nonce_str); // 与请求prepayId时值一致
			map.put("package", "Sign=WXPay"); // 固定常量
			map.put("partnerid", ConstantUtil.PARTNER_ID);
		} else {
			map.put("code", 1);
			map.put("info", "获取prepayid失败");
		}
		return map;
	}

	/**
	 * 接收微信支付成功通知
	 * 
	 * @param request
	 * @param response
	 * @throws IOException
	 */
	// @Auth
	@RequestMapping(value = "notify")
	public void getnotify(HttpServletRequest request,
			HttpServletResponse response) throws IOException {
		System.out.println("微信支付回调");
		PrintWriter writer = response.getWriter();
		InputStream inStream = request.getInputStream();
		ByteArrayOutputStream outSteam = new ByteArrayOutputStream();
		byte[] buffer = new byte[1024];
		int len = 0;
		while ((len = inStream.read(buffer)) != -1) {
			outSteam.write(buffer, 0, len);
		}
		outSteam.close();
		inStream.close();
		String result = new String(outSteam.toByteArray(), "utf-8");
		System.out.println("微信支付通知结果：" + result);
		Map<String, String> map = null;
		try {
			/**
			 * 解析微信通知返回的信息
			 */
			map = XMLUtil.doXMLParse(result);
			
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		System.out.println("=========:" + result);
		// 若支付成功，则告知微信服务器收到通知
		if (map.get("return_code").equals("SUCCESS")) {
			if (map.get("result_code").equals("SUCCESS")) {

			}
		}
	}

	/*
	 *  // 获取openId   private String getUserOpenId(HttpServletRequest request)
	 * throws Exception {     String code = requestgetParameter("code");     if
	 * (code == null) {       String openId = requestgetParameter("openId");
	 *       return openId;     }     Oauth o = new Oauth();     String token =
	 * ogetToken(code);     JsonNode node = JsonUtilStringToJsonNode(token);
	 *     String openId = nodeget("openid")asText();     return openId;   }
	 */
	public static final String AUTHCODETOOPENID_URL_SUFFIX = "/tools/authcodetoopenid";

	// sandbox
	public static final String SANDBOX_MICROPAY_URL_SUFFIX = "/sandboxnew/pay/micropay";

	public Map<String, String> microPay(Map<String, String> reqData,
			int connectTimeoutMs, int readTimeoutMs,
			PrepayIdRequestHandler prepayReqHandler) throws Exception {
		String url;

		url = SANDBOX_MICROPAY_URL_SUFFIX;// 沙箱

		reqData.put("appid", ConstantUtil.APP_ID);
		reqData.put("mch_id", ConstantUtil.MCH_ID);
		reqData.put("nonce_str", WXUtil.getNonceStr());

		reqData.put("sign_type", "MD5");
		reqData.put("sign", prepayReqHandler.createMD5Sign());

		String msgUUID = reqData.get("nonce_str");

		// String respXml = this.requestWithoutCert(url, reqData,
		// connectTimeoutMs, readTimeoutMs);
		String respXml = sendPrepay(reqData);
		return XMLUtil.doXMLParse(respXml);
	}

	/**
	 * 不需要证书的请求
	 * 
	 * @param urlSuffix
	 *            String
	 * @param reqData
	 *            向wxpay post的请求数据
	 * @param connectTimeoutMs
	 *            超时时间，单位是毫秒
	 * @param readTimeoutMs
	 *            超时时间，单位是毫秒
	 * @return API返回数据
	 * @throws Exception
	 */
	public String requestWithoutCert(String urlSuffix,
			Map<String, String> reqData, int connectTimeoutMs, int readTimeoutMs)
			throws Exception {
		String msgUUID = reqData.get("nonce_str");
		String resp = sendPrepay(reqData);
		return resp;
	}

	// 提交预支付
	public String sendPrepay(Map<String, String> reqData) throws Exception {
		String prepayid = "";

		Set es = reqData.entrySet();

		Iterator it = es.iterator();
		StringBuffer sb = new StringBuffer("<xml>");
		while (it.hasNext()) {
			Map.Entry entry = (Map.Entry) it.next();
			String k = (String) entry.getKey();
			String v = (String) entry.getValue();
			sb.append("<" + k + ">" + v + "</" + k + ">");
		}
		sb.append("</xml>");
		String params = sb.substring(0);
		System.out.println("请求参数：" + params);
		String requestUrl = SANDBOX_MICROPAY_URL_SUFFIX;
		System.out.println("请求url：" + requestUrl);
		TenpayHttpClient httpClient = new TenpayHttpClient();
		httpClient.setReqContent(requestUrl);
		String resContent = "";
		if (httpClient.callHttpPost(requestUrl, params)) {
			resContent = httpClient.getResContent();
			System.out.println("获取prepayid的返回值：" + resContent);
			Map<String, String> map = XMLUtil.doXMLParse(resContent);

			for (String key : map.keySet()) {
				System.out.println(key + "-------***---------" + map.get(key));
			}

			if (map.containsKey("prepay_id"))
				prepayid = map.get("prepay_id");
		}
		return resContent;
	}

	@RequestMapping(value = "qrcode")
	public String getQrcode(HttpServletRequest request,
			HttpServletResponse response, Model model) throws Exception {
		Map<String, Object> map = new HashMap<String, Object>();
		// 获取生成预支付订单的请求类
		PrepayIdRequestHandler prepayReqHandler = new PrepayIdRequestHandler(
				request, response);

		// System.out.println(microPay(new
		// HashMap<String,String>(),3000,3000,prepayReqHandler));

		String totalFee = request.getParameter("total_fee");
		int total_fee = (int) (Float.valueOf(totalFee) * 100);
		System.out.println("total:" + total_fee);
		System.out.println("total_fee:" + total_fee);
		
		prepayReqHandler.setParameter("appid", ConstantUtil.APP_ID);
		prepayReqHandler.setParameter("body", ConstantUtil.BODY);
		prepayReqHandler.setParameter("mch_id", ConstantUtil.MCH_ID);
		String nonce_str = WXUtil.getNonceStr();
		prepayReqHandler.setParameter("nonce_str", nonce_str);
		prepayReqHandler.setParameter("notify_url", ConstantUtil.NOTIFY_URL);
		out_trade_no = String.valueOf(UUID.next());
		prepayReqHandler.setParameter("out_trade_no", out_trade_no);
		prepayReqHandler.setParameter("spbill_create_ip",
				request.getRemoteAddr());
		String timestamp = WXUtil.getTimeStamp();
		prepayReqHandler.setParameter("time_start", timestamp);
		System.out.println(String.valueOf(total_fee));
		prepayReqHandler.setParameter("total_fee", String.valueOf(total_fee));
		prepayReqHandler.setParameter("trade_type", "NATIVE");// JSAPI NATIVE
																// APP
		/**
		 * 注意签名（sign）的生成方式，具体见官方文档（传参都要参与生成签名，且参数名按照字典序排序，最后接上APP_KEY,转化成大写）
		 */
		prepayReqHandler.setParameter("sign", prepayReqHandler.createMD5Sign());
		prepayReqHandler.setGateUrl(ConstantUtil.GATEURL);
		String resContent = prepayReqHandler.sendPrepay();

		String code_url = "";
		map = XMLUtil.doXMLParse(resContent);

		for (String key : map.keySet()) {
			// System.out.println(key+"-------***---------"+map.get(key));

			if (map.containsKey("code_url")) {
				code_url = map.get("code_url").toString();
				ByteArrayOutputStream out = QRCode.from(code_url)
						.to(ImageType.PNG).withSize(200, 200).stream();
				byte[] s = out.toByteArray();

				BASE64Encoder encoder = new BASE64Encoder();
				String binary = encoder.encodeBuffer(s).trim();
				model.addAttribute("qrimg", binary);
			}

		}

		return "modules/platform/qrpayForm";
	}

}